home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / nethack.lha / nethack-3.1 / src / bones.c < prev    next >
C/C++ Source or Header  |  1993-01-08  |  9KB  |  386 lines

  1. /*    SCCS Id: @(#)bones.c    3.1    93/01/07    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985,1993. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6. #include "lev.h"
  7.  
  8. #ifdef MFLOPPY
  9. extern char bones[];    /* from files.c */
  10. extern long bytes_counted;
  11. #endif
  12.  
  13. static boolean FDECL(no_bones_level, (d_level *));
  14. #ifdef TUTTI_FRUTTI
  15. static void FDECL(goodfruit, (int));
  16. #endif
  17. static void FDECL(resetobjs,(struct obj *,BOOLEAN_P));
  18. static void FDECL(drop_upon_death, (struct monst *, struct obj *));
  19.  
  20. static boolean
  21. no_bones_level(lev)
  22. d_level *lev;
  23. {
  24.     extern d_level save_dlevel;        /* in do.c */
  25.     s_level *sptr;
  26.  
  27.     if (ledger_no(&save_dlevel)) assign_level(lev, &save_dlevel);
  28.  
  29.     return (((sptr = Is_special(lev)) && !sptr->boneid)
  30.         || !dungeons[lev->dnum].boneid
  31.            /* no bones on the last or multiway branch levels */
  32.            /* in any dungeon (level 1 isn't multiway).       */
  33.         || Is_botlevel(lev) || (Is_branchlev(lev) && lev->dlevel > 1)
  34.            /* no bones in the invocation level               */
  35.         || (In_hell(lev) && lev->dlevel == dunlevs_in_dungeon(lev) - 1)
  36.         );
  37. }
  38.  
  39. #ifdef TUTTI_FRUTTI
  40. static void
  41. goodfruit(id)
  42. int id;
  43. {
  44.     register struct fruit *f;
  45.  
  46.     for(f=ffruit; f; f=f->nextf) {
  47.         if(f->fid == -id) {
  48.             f->fid = id;
  49.             return;
  50.         }
  51.     }
  52. }
  53. #endif
  54.  
  55. static void
  56. resetobjs(ochain,restore)
  57. struct obj *ochain;
  58. boolean restore;
  59. {
  60.     struct obj *otmp;
  61.  
  62.     for (otmp = ochain; otmp; otmp = otmp->nobj) {
  63.         if (otmp->cobj)
  64.             resetobjs(otmp->cobj,restore);
  65.  
  66.         if (((otmp->otyp != CORPSE || otmp->corpsenm < PM_ARCHEOLOGIST)
  67.             && otmp->otyp != STATUE)
  68.             && (!otmp->oartifact ||
  69.                 (exist_artifact(otmp->otyp,ONAME(otmp)) && restore))) {
  70.             otmp->oartifact = 0;
  71.             otmp->onamelth = 0;
  72.             *ONAME(otmp) = '\0';
  73.         } else if (otmp->oartifact && restore)
  74.             artifact_exists(otmp,ONAME(otmp),TRUE);
  75.         if (!restore) {
  76.             /* resetting the o_id's after getlev has carefully
  77.              * created proper new ones via restobjchn is a Bad
  78.              * Idea */
  79.             otmp->o_id = 0;
  80.             if(objects[otmp->otyp].oc_uses_known) otmp->known = 0;
  81.             otmp->dknown = otmp->bknown = 0;
  82.             otmp->rknown = 0;
  83.             otmp->invlet = 0;
  84. #ifdef TUTTI_FRUTTI
  85.             if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe);
  86. #endif
  87. #ifdef MAIL
  88.             if (otmp->otyp == SCR_MAIL) otmp->spe = 1;
  89. #endif
  90. #ifdef POLYSELF
  91.             if (otmp->otyp == EGG) otmp->spe = 0;
  92. #endif
  93.             if(otmp->otyp == AMULET_OF_YENDOR) {
  94.                 /* no longer the actual amulet */
  95.                 otmp->otyp = FAKE_AMULET_OF_YENDOR;
  96.                 curse(otmp);
  97.             }
  98.             if(otmp->otyp == CANDELABRUM_OF_INVOCATION) {
  99.                 if(otmp->spe > 0) { /* leave candles, if any */
  100.                     otmp->otyp = WAX_CANDLE;
  101.                 otmp->age = 50L;  /* assume used */
  102.                 otmp->quan = (long)otmp->spe;
  103.                 otmp->lamplit = 0;
  104.                 otmp->spe = 0;
  105.                 } else obfree(otmp, (struct obj *)0);
  106.             }
  107.             if(otmp->otyp == BELL_OF_OPENING) otmp->otyp = BELL;
  108.             if(otmp->otyp == SPE_BOOK_OF_THE_DEAD) {
  109.                 otmp->otyp = SPE_MAGIC_MISSILE +
  110.                                 rn2(SPE_BLANK_PAPER -
  111.                           SPE_MAGIC_MISSILE + 1);
  112.                 curse(otmp);
  113.             }
  114.         }
  115.     }            
  116. }
  117.  
  118. static void
  119. drop_upon_death(mtmp, cont)
  120. struct monst *mtmp;
  121. struct obj *cont;
  122. {
  123.     struct obj *otmp = invent;
  124.     while(otmp) {
  125.         otmp->owornmask = 0;
  126.         otmp->lamplit = 0;
  127. #ifdef TUTTI_FRUTTI
  128.         if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe);
  129. #endif
  130.         if(rn2(5)) curse(otmp);
  131.         if(!mtmp && !cont) place_object(otmp, u.ux, u.uy);
  132.         if(!otmp->nobj) {
  133.             if (mtmp) {
  134.                 otmp->nobj = mtmp->minvent;
  135.                 mtmp->minvent = invent;
  136.             } else if (cont) {
  137.                 otmp->nobj = cont->cobj;
  138.                 cont->cobj = invent;
  139.             } else {
  140.                 otmp->nobj = fobj;
  141.                 fobj = invent;
  142.             }
  143.             invent = 0;    /* superfluous */
  144.             break;
  145.         }
  146.         otmp = otmp->nobj;
  147.     }
  148.     if(u.ugold) {
  149.         if (mtmp) mtmp->mgold = u.ugold;
  150.         else mkgold(u.ugold, u.ux, u.uy);
  151.     }
  152. }
  153.  
  154. /* save bones and possessions of a deceased adventurer */
  155. void
  156. savebones()
  157. {
  158.     register int fd, x, y;
  159.     register struct trap *ttmp;
  160.     register struct monst *mtmp, *mtmp2;
  161. #ifdef TUTTI_FRUTTI
  162.     struct fruit *f;
  163. #endif
  164.     char *bonesid;
  165.  
  166.     if(ledger_no(&u.uz) <= 0 || ledger_no(&u.uz) > maxledgerno()) return;
  167.     if(no_bones_level(&u.uz)) return; /* no bones for specific levels */
  168.     if(!rn2(1 + (depth(&u.uz)>>2)) /* fewer ghosts on low levels */
  169. #ifdef WIZARD
  170.         && !wizard
  171. #endif
  172.         ) return;
  173. #ifdef EXPLORE_MODE
  174.     /* don't let multiple restarts generate multiple copies of objects
  175.      * in bones files */
  176.     if(discover) return;
  177. #endif
  178.  
  179.     fd = open_bonesfile(&u.uz, &bonesid);
  180.     if (fd >= 0) {
  181.         (void) close(fd);
  182.         compress_bonesfile();
  183. #ifdef WIZARD
  184.         if(wizard)
  185.             pline("Bones file already exists.");
  186. #endif
  187.         return;
  188.     }
  189.  
  190. #ifdef WALKIES
  191.     unleash_all();
  192. #endif
  193.     /* in case these characters are not in their home bases */
  194.     mtmp2 = fmon;
  195.     while((mtmp = mtmp2)) {
  196.         mtmp2 = mtmp->nmon;
  197.         if(mtmp->iswiz || mtmp->data == &mons[PM_MEDUSA]) mongone(mtmp);
  198.     }
  199. #ifdef TUTTI_FRUTTI
  200.     /* mark all fruits as nonexistent; when we come to them we'll mark
  201.      * them as existing (using goodfruit())
  202.      */
  203.     for(f=ffruit; f; f=f->nextf) f->fid = -f->fid;
  204. #endif
  205.  
  206.     /* check iron balls separately--maybe they're not carrying it */
  207.     if (uball) uball->owornmask = uchain->owornmask = 0;
  208.  
  209.     /* dispose of your possessions, usually cursed */
  210.     if (u.ugrave_arise == -2) {
  211.         struct obj *otmp;
  212.  
  213.         /* embed your possessions in your statue */
  214.         otmp = mk_named_object(STATUE,
  215. #ifdef POLYSELF
  216.                     u.mtimedone ? uasmon :
  217. #endif
  218.                     player_mon(), 
  219.                     u.ux, u.uy, plname,
  220.                     (int)strlen(plname));
  221.         if (!otmp) return;
  222.         drop_upon_death(mtmp = (struct monst *)0, otmp);
  223.     } else if (u.ugrave_arise == -1) {
  224.         /* drop everything */
  225.         drop_upon_death((struct monst *)0, (struct obj *)0);
  226.         /* trick makemon() into allowing monster creation
  227.          * on your location
  228.          */
  229.         in_mklev = TRUE;
  230.         mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy);
  231.         in_mklev = FALSE;
  232.         if (!mtmp) return;
  233.         Strcpy((char *) mtmp->mextra, plname);
  234.     } else {
  235.         /* give your possessions to the monster you become */
  236.         in_mklev = TRUE;
  237.         mtmp = makemon(&mons[u.ugrave_arise], u.ux, u.uy);
  238.         in_mklev = FALSE;
  239.         if (!mtmp) return;
  240.         mtmp = christen_monst(mtmp, plname);
  241.         newsym(u.ux, u.uy);
  242.         Your("body rises from the dead as %s...",
  243.             an(mons[u.ugrave_arise].mname));
  244.         display_nhwindow(WIN_MESSAGE, FALSE);
  245.         drop_upon_death(mtmp, (struct obj *)0);
  246. #ifdef MUSE
  247.         m_dowear(mtmp, TRUE);
  248. #endif
  249.     }
  250.     if (mtmp) {
  251.         mtmp->m_lev = (u.ulevel ? u.ulevel : 1);
  252.         mtmp->mhp = mtmp->mhpmax = u.uhpmax;
  253.         mtmp->msleep = 1;
  254.     }
  255.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  256.         resetobjs(mtmp->minvent,FALSE);
  257.         mtmp->m_id = 0;
  258.         mtmp->mlstmv = 0L;
  259.         if(mtmp->mtame) mtmp->mtame = mtmp->mpeaceful = 0;
  260.     }
  261.     for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) {
  262.             if(ttmp->ttyp == MAGIC_PORTAL) deltrap(ttmp);
  263.         ttmp->tseen = 0;
  264.     }
  265.     resetobjs(fobj,FALSE);
  266.  
  267.     /* Clear all memory from the level. */
  268.     for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++) {
  269.         levl[x][y].seen = levl[x][y].waslit = 0;
  270.         levl[x][y].glyph = cmap_to_glyph(S_stone);
  271.     }
  272.  
  273.     fd = create_bonesfile(&u.uz, &bonesid);
  274.     if(fd < 0) {
  275. #ifdef WIZARD
  276.         if(wizard)
  277.             pline("Cannot create bones file - create failed");
  278. #endif
  279.         return;
  280.     }
  281.  
  282.     bufon(fd);
  283. #ifdef MFLOPPY  /* check whether there is room */
  284.     savelev(fd, ledger_no(&u.uz), COUNT_SAVE);
  285. # ifdef TUTTI_FRUTTI
  286.     /* this is in the opposite order from the real save, but savelev()
  287.      * initializes bytes_counted to 0, so doing savefruitchn() first is
  288.      * useless; the extra bflush() at the end of savelev() may increase
  289.      * bytes_counted by a couple over what the real usage will be
  290.      */
  291.     savefruitchn(fd, COUNT_SAVE);
  292.     bflush(fd);
  293. # endif
  294.     if (bytes_counted > freediskspace(bones)) {    /* not enough room */
  295. # ifdef WIZARD
  296.         if (wizard)
  297.             pline("Insufficient space to create bones file.");
  298. # endif
  299.         (void) close(fd);
  300.         delete_bonesfile(&u.uz);
  301.         return;
  302.     }
  303.     co_false();    /* make sure bonesid and savefruitchn get written */
  304. #endif /* MFLOPPY */
  305.  
  306.     bwrite(fd, (genericptr_t) bonesid, 7);    /* DD.nnn */
  307. #ifdef TUTTI_FRUTTI
  308.     savefruitchn(fd, WRITE_SAVE | FREE_SAVE);
  309. #endif
  310.     savelev(fd, ledger_no(&u.uz), WRITE_SAVE | FREE_SAVE);
  311.     bclose(fd);
  312.     compress_bonesfile();
  313. }
  314.  
  315. int
  316. getbones()
  317. {
  318.     register int fd;
  319.     register int ok;
  320.     char *bonesid, oldbonesid[7];
  321.  
  322. #ifdef EXPLORE_MODE
  323.     if(discover)        /* save bones files for real games */
  324.         return(0);
  325. #endif
  326.     /* wizard check added by GAN 02/05/87 */
  327.     if(rn2(3)    /* only once in three times do we find bones */
  328. #ifdef WIZARD
  329.         && !wizard
  330. #endif
  331.         ) return(0);
  332.     if(no_bones_level(&u.uz)) return(0);
  333.     fd = open_bonesfile(&u.uz, &bonesid);
  334.     if (fd < 0) return(0);
  335.  
  336.     if((ok = uptodate(fd)) != 0){
  337. #ifdef WIZARD
  338.         if(wizard)  {
  339.             if(yn("Get bones?") == 'n') {
  340.                 (void) close(fd);
  341.                 compress_bonesfile();
  342.                 return(0);
  343.             }
  344.         }
  345. #endif
  346.         minit();    /* ZEROCOMP */
  347.         mread(fd, (genericptr_t) oldbonesid, 7);    /* DD.nnn */
  348.         if (strcmp(bonesid, oldbonesid)) {
  349. #ifdef WIZARD
  350.             if (wizard) {
  351.                 pline("This is bones level '%s', not '%s'!",
  352.                     oldbonesid, bonesid);
  353.                 ok = FALSE;    /* won't die of trickery */
  354.             }
  355. #endif
  356.             trickery();
  357.         } else {
  358.             register struct monst *mtmp;
  359.  
  360.             getlev(fd, 0, 0, TRUE);
  361.  
  362.             /* to correctly reset named artifacts on the level */
  363.             for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  364.                 resetobjs(mtmp->minvent,TRUE);
  365.             resetobjs(fobj,TRUE);
  366.         }
  367.     }
  368.     (void) close(fd);
  369.  
  370. #ifdef WIZARD
  371.     if(wizard) {
  372.         if(yn("Unlink bones?") == 'n') {
  373.             compress_bonesfile();
  374.             return(ok);
  375.         }
  376.     }
  377. #endif
  378.     if (!delete_bonesfile(&u.uz)) {
  379.         pline("Cannot unlink bones.");
  380.         return(0);
  381.     }
  382.     return(ok);
  383. }
  384.  
  385. /*bones.c*/
  386.